// ProjectName: go-learn-demo
// PackageName: _1_channel
// Description: channel的基本定义
// Author: hy.bai
// Date: 2025-07-30 19:10

package channelybxb

import "fmt"

func TestChanDefinie() {

	// 声明一个chan类型的变量。
	var ch1 chan int
	var ch2 chan string
	var ch3 chan []int
	// 注意：此时并没有初始化chan。

	fmt.Println(ch1, ch2, ch3) // (不会报错)打印结果：<nil> <nil> <nil>
}

func TestChanDefinie1() {

	// 声明一个chan类型的变量。
	var ch1 chan int = make(chan int, 10)      // 初始化一个长度为10，元素类型为int的管道
	var ch2 chan string = make(chan string, 4) // 初始化一个长度为4，元素类型为string的管道
	var ch3 chan []int = make(chan []int, 5)   // 初始化一个长度为5，元素类型为切片([]int)的管道
	// 注意：此时已经通过make函数把channel进行了初始化。即：已经申请了内存空间。

	fmt.Println(ch1, ch2, ch3) // 打印结果：0xc000106000 0xc000108000 0xc000108070
}

// 把数据写入channel中。
func SaveAndGetDataChan() {
	var ch1 chan int = make(chan int, 3)
	// 把数据写入chan中。
	ch1 <- 10
	ch1 <- 20
	ch1 <- 30
	// ch1 <- 50
	// 注意：如果写入数据超过Chan的容量时，会报错：fatal error: all goroutines are asleep - deadlock!(死锁)
	// --------------------------------------------------------------------------------------------
	// 从chan中读取数据
	var abc1 = <-ch1               //  <-ch1:是一个整体
	fmt.Printf("abc1: %v\n", abc1) // 获取第1个放入的元素(先进先出)

	// 读取出来一个数据之后，是否可写呢？
	ch1 <- 50
	// 答案：可以

	var abc2 = <-ch1
	fmt.Printf("abc2: %v\n", abc2) // 获取第2个放入的元素(先进先出)

	var abc3 = <-ch1
	fmt.Printf("abc3: %v\n", abc3) // 获取第3个放入的元素(先进先出)

	var abc4 = <-ch1
	fmt.Printf("abc4: %v\n", abc4) // 获取第4个放入的元素(先进先出)
	// 注意：如果读取数据超过Chan的容量时，会报错：fatal error: all goroutines are asleep - deadlock!(死锁)
}

// 使用for循环优雅读取chan中的数据
func TestForChanData() {
	// 初始化Chan对象
	var length = 5
	var ch1 chan int = make(chan int, length)
	for i := 0; i < length; i++ {
		ch1 <- 10 * (i + 1)
	}
	close(ch1) // 关闭channel
	// for range循环，在Channel的循环遍历中，只有一个value
	for value := range ch1 { // 特性：channel close后，for range读取完所有元素之后会自动退出
		fmt.Printf("value: %v\n", value)
	}
}
func TestChanData() {
	var ch1 chan int = make(chan int, 1)
	ch1 <- 10
	close(ch1)
	var value1, ok1 = <-ch1
	fmt.Printf("value1是:%v, ok1是%v\n", value1, ok1) // value1是:10, ok1是true
	var value2, ok2 = <-ch1
	fmt.Printf("value2是:%v, ok2是%v\n", value2, ok2) // value2是:0, ok2是false

	// 注意:1.调用close函数关闭channel时，获取channel的值时，如果channel中，没有值，取出的是零值(默认值)
	// 即：int的默认值是0，bool的默认值false，而ok是false。
}
